Skip to content

Conversation

@AkhileshNegi
Copy link
Collaborator

@AkhileshNegi AkhileshNegi commented Nov 13, 2025

Summary

When creating a new migration, it populates the new migration with lot of changes dues to inconsistency in model and DB schema. This PR addresses those issues

Checklist

Before submitting a pull request, please ensure that you mark these task.

  • Ran fastapi run --reload app/main.py or docker compose up in the repository root and test.
  • If you've fixed a bug or added code that is tested and has test cases.

Summary by CodeRabbit

  • Chores

    • Migrated several JSON fields to a more efficient storage format and added indexes to speed queries and API responses.
    • Adjusted foreign-key deletion behavior and nullability to improve data integrity for evaluation and batch-job records.
    • Minor schema and metadata cleanups to standardize column definitions.
  • Refactor

    • Reorganized model declarations to consolidate indexing and storage optimizations for better performance.

@coderabbitai
Copy link

coderabbitai bot commented Nov 13, 2025

Walkthrough

Converts several JSON columns to JSONB, adjusts foreign-key on-delete semantics (notably evaluation_run↔batch_job and OpenAI conversation FKs) via a new Alembic revision, tightens nullability/indexing for batch_job and evaluation_run fields, and removes some inline alembic comments/formatting.

Changes

Cohort / File(s) Summary
Alembic: evaluation constraints migration
backend/app/alembic/versions/633e69806207_evaluation_update_constraints.py
New revision: converts evaluation_run.config and evaluation_run.score to JSONB, drops and re-creates FKs involving evaluation_runbatch_job (setting ON DELETE SET NULL) and re-creates two OpenAI conversation FKs during upgrade/downgrade; downgrade reverses types and restores prior FKs.
Alembic: create evaluation_run table (cosmetic)
backend/app/alembic/versions/6fe772038a5a_create_evaluation_run_table.py
Formatting/comment cleanup and minor import/column comment removals; no behavioral changes to schema definitions.
Models: BatchJob schema
backend/app/models/batch_job.py
Adds __table_args__ composite indexes on (provider_status, organization_id) and (provider_status, project_id); makes organization_id and project_id non-nullable with ondelete="CASCADE" and indexed; converts config to explicit JSONB Column; introduces error_message as Text Column and adds explicit indexing/metadata on several fields.
Models: Evaluation schema
backend/app/models/evaluation.py
Replaces JSON with JSONB for dataset_metadata, config, and score (with explicit nullability), makes embedding_batch_job_id nullable (ON DELETE SET NULL), and adds composite indices on (status, organization_id) and (status, project_id).

Sequence Diagram(s)

(Skipped — changes are schema/migration and do not introduce new runtime control flow.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas needing extra attention:

  • backend/app/alembic/versions/633e69806207_evaluation_update_constraints.py: verify FK recreation names, ON DELETE behaviors, and that downgrade cleanly restores types and constraints.
  • backend/app/models/batch_job.py: ensure organization_id/project_id non-null + ondelete="CASCADE" matches data expectations and related models.
  • backend/app/models/evaluation.py: confirm JSON→JSONB column definitions, nullability, and index names to avoid collisions with existing indexes.

Possibly related PRs

  • Evaluation #405 — touches the same evaluation models and migrations (JSON→JSONB and FK ondelete adjustments), likely related.

Suggested reviewers

  • kartpop
  • vijay-T4D
  • nishika26

Poem

🐇 I nibbled schemas in the moonlight glow,
Swapped JSON for JSONB — neat rows in tow.
Indexes planted, FKs set with care,
Migrations hum softly through the air.
Hop, click, migrate — a rabbit's happy flair.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Evaluation: Migration Cleanups' directly matches the PR's main objective of fixing inconsistencies between application models and database schema, and cleaning up migration issues.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch enhancement/evaluation-migrations

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Nov 13, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@AkhileshNegi AkhileshNegi marked this pull request as ready for review November 13, 2025 11:17
@AkhileshNegi AkhileshNegi self-assigned this Nov 13, 2025
@AkhileshNegi AkhileshNegi added the bug Something isn't working label Nov 13, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa704b9 and 9585979.

📒 Files selected for processing (4)
  • backend/app/alembic/versions/633e69806207_evaluation_update_constraints.py (1 hunks)
  • backend/app/alembic/versions/6fe772038a5a_create_evaluation_run_table.py (1 hunks)
  • backend/app/models/batch_job.py (2 hunks)
  • backend/app/models/evaluation.py (6 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Use type hints in Python code (Python 3.11+ project)

Files:

  • backend/app/alembic/versions/633e69806207_evaluation_update_constraints.py
  • backend/app/alembic/versions/6fe772038a5a_create_evaluation_run_table.py
  • backend/app/models/evaluation.py
  • backend/app/models/batch_job.py
backend/app/models/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Define SQLModel entities (database tables and domain objects) in backend/app/models/

Files:

  • backend/app/models/evaluation.py
  • backend/app/models/batch_job.py
🔇 Additional comments (3)
backend/app/alembic/versions/6fe772038a5a_create_evaluation_run_table.py (1)

173-197: Embedding FK stays aligned with later migrations.

Thanks for keeping embedding_batch_job_id nullable and consistent with the follow-up constraint tweaks—this keeps the base revision compatible with 633e69806207.

backend/app/models/evaluation.py (1)

94-195: Model changes match the new schema.

Nice job moving these payload fields onto JSONB and wiring up the status indexes—this lines up with the migrations cleanly.

backend/app/models/batch_job.py (1)

18-119: Schema metadata and indexes look solid.

The richer column metadata plus the new provider_status composite indexes will make querying and migrations saner—looks good.

Comment on lines 42 to 65
op.drop_constraint(
"openai_conversation_organization_id_fkey1",
"openai_conversation",
type_="foreignkey",
)
op.drop_constraint(
"openai_conversation_project_id_fkey1",
"openai_conversation",
type_="foreignkey",
)
op.create_foreign_key(
"evaluation_run_batch_job_id_fkey",
"evaluation_run",
"batch_job",
["batch_job_id"],
["id"],
)
op.create_foreign_key(
"fk_evaluation_run_embedding_batch_job_id",
"evaluation_run",
"batch_job",
["embedding_batch_job_id"],
["id"],
)
Copy link

@coderabbitai coderabbitai bot Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Do not leave openai_conversation without foreign keys.

The upgrade drops openai_conversationorganization/project FKs but never recreates them, so the table permanently loses referential integrity while the downgrade adds them back. This will allow orphaned rows as soon as the migration runs. Please recreate the FKs in the upgrade after re-adding the evaluation_run constraints.

     op.create_foreign_key(
         "fk_evaluation_run_embedding_batch_job_id",
         "evaluation_run",
         "batch_job",
         ["embedding_batch_job_id"],
         ["id"],
     )
+    op.create_foreign_key(
+        "openai_conversation_organization_id_fkey1",
+        "openai_conversation",
+        "organization",
+        ["organization_id"],
+        ["id"],
+    )
+    op.create_foreign_key(
+        "openai_conversation_project_id_fkey1",
+        "openai_conversation",
+        "project",
+        ["project_id"],
+        ["id"],
+    )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
op.drop_constraint(
"openai_conversation_organization_id_fkey1",
"openai_conversation",
type_="foreignkey",
)
op.drop_constraint(
"openai_conversation_project_id_fkey1",
"openai_conversation",
type_="foreignkey",
)
op.create_foreign_key(
"evaluation_run_batch_job_id_fkey",
"evaluation_run",
"batch_job",
["batch_job_id"],
["id"],
)
op.create_foreign_key(
"fk_evaluation_run_embedding_batch_job_id",
"evaluation_run",
"batch_job",
["embedding_batch_job_id"],
["id"],
)
op.drop_constraint(
"openai_conversation_organization_id_fkey1",
"openai_conversation",
type_="foreignkey",
)
op.drop_constraint(
"openai_conversation_project_id_fkey1",
"openai_conversation",
type_="foreignkey",
)
op.create_foreign_key(
"evaluation_run_batch_job_id_fkey",
"evaluation_run",
"batch_job",
["batch_job_id"],
["id"],
)
op.create_foreign_key(
"fk_evaluation_run_embedding_batch_job_id",
"evaluation_run",
"batch_job",
["embedding_batch_job_id"],
["id"],
)
op.create_foreign_key(
"openai_conversation_organization_id_fkey1",
"openai_conversation",
"organization",
["organization_id"],
["id"],
)
op.create_foreign_key(
"openai_conversation_project_id_fkey1",
"openai_conversation",
"project",
["project_id"],
["id"],
)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this has been fixed, can you resolve this comment

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the full contents of the migration file to see if the issue has been fixed
cat backend/app/alembic/versions/633e69806207_evaluation_update_constraints.py

Length of output: 3374


@nishika26, I've checked the migration file and the issue has NOT been fixed.

The upgrade() function still drops the openai_conversation foreign keys (lines 42-51) but never recreates them. Only the evaluation_run foreign keys are being recreated (lines 52-64).

This means after the migration runs, the openai_conversation table will permanently lose referential integrity to organization and project tables, allowing orphaned records.

What needs to be fixed:

Add these lines at the end of the upgrade() function (after line 64):

    op.create_foreign_key(
        "openai_conversation_organization_id_fkey1",
        "openai_conversation",
        "organization",
        ["organization_id"],
        ["id"],
    )
    op.create_foreign_key(
        "openai_conversation_project_id_fkey1",
        "openai_conversation",
        "project",
        ["project_id"],
        ["id"],
    )

Without this fix, I cannot resolve this comment as it represents a critical data integrity issue.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh sorry coderabbit, my comment was towards @AkhileshNegi

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Comment on lines 42 to 65
op.drop_constraint(
"openai_conversation_organization_id_fkey1",
"openai_conversation",
type_="foreignkey",
)
op.drop_constraint(
"openai_conversation_project_id_fkey1",
"openai_conversation",
type_="foreignkey",
)
op.create_foreign_key(
"evaluation_run_batch_job_id_fkey",
"evaluation_run",
"batch_job",
["batch_job_id"],
["id"],
)
op.create_foreign_key(
"fk_evaluation_run_embedding_batch_job_id",
"evaluation_run",
"batch_job",
["embedding_batch_job_id"],
["id"],
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this has been fixed, can you resolve this comment

),
description="S3 URL of raw batch output file",
)
total_items: int = Field(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all the Fields,

You don’t need to use sa_column here. SQLModel already infers the SQLAlchemy column from the type annotation + Field() metadata.

total_items: int = Field( default=0, description="Total number of items in the batch" )

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
backend/app/alembic/versions/633e69806207_evaluation_update_constraints.py (2)

21-34: Verify JSON to JSONB conversion with existing data.

PostgreSQL can automatically convert JSON to JSONB data, but you should verify this migration will succeed if the evaluation_run table contains existing records. The conversion is generally safe, but JSONB has stricter validation and different storage format.

#!/bin/bash
# Check if there are any data migration scripts or tests for this conversion
fd -e py -e sql | xargs rg -l "JSON.*JSONB|jsonb.*migration" 

# Search for evaluation_run data seeding or fixtures
rg -n "evaluation_run" --type=py -g "*seed*" -g "*fixture*" -g "*test*" | head -20

43-66: Critical: openai_conversation foreign keys are permanently lost.

The upgrade() function drops the openai_conversation foreign key constraints (lines 43-52) but never recreates them. Only the evaluation_run foreign keys are recreated (lines 53-66). This permanently removes referential integrity for the openai_conversation table, allowing orphaned records to accumulate when organizations or projects are deleted.

The downgrade() function correctly recreates these constraints (lines 107-120), confirming they should exist.

Apply this diff to recreate the openai_conversation foreign keys after the evaluation_run foreign keys:

     op.create_foreign_key(
         "fk_evaluation_run_embedding_batch_job_id",
         "evaluation_run",
         "batch_job",
         ["embedding_batch_job_id"],
         ["id"],
     )
+    op.create_foreign_key(
+        "openai_conversation_organization_id_fkey1",
+        "openai_conversation",
+        "organization",
+        ["organization_id"],
+        ["id"],
+    )
+    op.create_foreign_key(
+        "openai_conversation_project_id_fkey1",
+        "openai_conversation",
+        "project",
+        ["project_id"],
+        ["id"],
+    )
🧹 Nitpick comments (1)
backend/app/models/batch_job.py (1)

27-124: Consider whether explicit sa_column definitions are necessary.

A past review comment (line 109) noted that SQLModel already infers SQLAlchemy columns from type annotations and Field() metadata, questioning the necessity of explicit sa_column usage. While these definitions provide explicit control over the database schema (comments, nullability, indexing), they add significant verbosity.

If this explicit approach is intentional for this PR's goal of ensuring model-schema consistency, it's acceptable. However, for future work, consider whether the same result can be achieved more concisely using SQLModel's inference capabilities.

Example of a more concise approach (using provider field as an example):

provider: str = Field(
    description="LLM provider name (e.g., 'openai', 'anthropic')",
    # SQLModel infers: Column(String, nullable=False)
)

versus the current:

provider: str = Field(
    sa_column=Column(
        String,
        nullable=False,
        comment="LLM provider name (e.g., 'openai', 'anthropic')",
    ),
    description="LLM provider name (e.g., 'openai', 'anthropic')",
)

Based on learnings

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9585979 and 284cac4.

📒 Files selected for processing (3)
  • backend/app/alembic/versions/633e69806207_evaluation_update_constraints.py (1 hunks)
  • backend/app/alembic/versions/6fe772038a5a_create_evaluation_run_table.py (2 hunks)
  • backend/app/models/batch_job.py (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Use type hints in Python code (Python 3.11+ project)

Files:

  • backend/app/alembic/versions/6fe772038a5a_create_evaluation_run_table.py
  • backend/app/models/batch_job.py
  • backend/app/alembic/versions/633e69806207_evaluation_update_constraints.py
backend/app/models/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Define SQLModel entities (database tables and domain objects) in backend/app/models/

Files:

  • backend/app/models/batch_job.py
🧠 Learnings (1)
📚 Learning: 2025-10-08T12:05:01.317Z
Learnt from: CR
Repo: ProjectTech4DevAI/ai-platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-08T12:05:01.317Z
Learning: Applies to backend/app/models/**/*.py : Define SQLModel entities (database tables and domain objects) in backend/app/models/

Applied to files:

  • backend/app/alembic/versions/6fe772038a5a_create_evaluation_run_table.py
🧬 Code graph analysis (1)
backend/app/alembic/versions/633e69806207_evaluation_update_constraints.py (1)
backend/app/alembic/versions/6fe772038a5a_create_evaluation_run_table.py (2)
  • upgrade (21-224)
  • downgrade (227-244)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: checks (3.11.7, 6)
🔇 Additional comments (4)
backend/app/alembic/versions/6fe772038a5a_create_evaluation_run_table.py (2)

8-12: LGTM: Import reordering improves consistency.

The explicit import of sqlalchemy as sa earlier in the file and reordering of other imports is a cosmetic improvement that doesn't affect functionality.


173-173: The review comment conflates columns from different tables and misidentifies an inconsistency.

The batch_job table columns (lines 26-87) are in a separate table and do have descriptive comments. However, within the evaluation_run table itself, both batch_job_id (line 172) and embedding_batch_job_id (line 173) are consistently formatted as simple one-liners without comments. There is no inconsistency to address—the two foreign key columns in the same table are already treated uniformly.

Likely an incorrect or invalid review comment.

backend/app/models/batch_job.py (2)

19-22: LGTM: Composite indices improve query performance.

These composite indices on (provider_status, organization_id) and (provider_status, project_id) will optimize common query patterns for filtering batch jobs by status within specific organizations or projects.


127-132: LGTM: CASCADE deletion behavior maintains referential integrity.

The addition of ondelete="CASCADE" ensures that when an organization or project is deleted, related batch jobs are automatically removed, preventing orphaned records.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
backend/app/models/batch_job.py (1)

19-22: Let me do one final comprehensive search to check if there are any queries that use provider_status as the primary filtering criterion:

Revise composite index strategy to align with actual query patterns.

The query pattern in get_batches_by_type() filters by job_type first, then optionally by organization_id, project_id, and finally provider_status (lines 172-181, backend/app/crud/batch_job.py). However, the composite indexes are defined with provider_status as the leading column—the opposite order. Composite indexes should order columns by their usage in WHERE clauses, with the most frequently filtered columns first, to allow the optimizer to utilize them efficiently.

Consider restructuring indexes to match query patterns:

  • (job_type, organization_id) and (job_type, project_id) would better serve the actual filtering order
  • Alternatively, evaluate whether provider_status queries occur in isolation elsewhere to justify the current index design

The existing job_type field index and individual indexes on organization_id/project_id are appropriate.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 284cac4 and ff3b4c1.

📒 Files selected for processing (1)
  • backend/app/models/batch_job.py (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Use type hints in Python code (Python 3.11+ project)

Files:

  • backend/app/models/batch_job.py
backend/app/models/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Define SQLModel entities (database tables and domain objects) in backend/app/models/

Files:

  • backend/app/models/batch_job.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: checks (3.11.7, 6)
🔇 Additional comments (5)
backend/app/models/batch_job.py (5)

27-35: LGTM!

The addition of index=True on the job_type field is appropriate for query performance when filtering batch jobs by type. The descriptions enhance code documentation.


38-45: LGTM!

Using sa_column=Column(JSONB, nullable=False) is the correct approach here. While a past review comment mentioned that sa_column is not always necessary, JSONB is a PostgreSQL-specific type that SQLModel cannot automatically infer from dict[str, Any]. JSONB provides better query performance and indexing capabilities compared to the plain JSON type.


48-78: LGTM!

The explicit default=None on Optional fields is technically redundant (SQLModel infers None for Optional types), but it improves code clarity and is a harmless practice. The enhanced descriptions significantly improve documentation.


81-85: LGTM!

Using sa_column=Column(Text, nullable=True) is appropriate for error messages that might be lengthy. The Text type has no length limit in PostgreSQL, unlike VARCHAR, making it suitable for storing potentially long error messages or stack traces.


88-93: Now I need to examine the actual codebase to understand the batch_job model context and determine if CASCADE is already in the database or a new change:

Based on the web search results, CASCADE is a standard pattern in SQLModel/SQLAlchemy and is commonly used in real-world batch systems. However, I still need to examine the actual codebase to verify the specific context. Let me search for the batch_job model and related files:Based on my research, I have gathered sufficient information to address the review comment. The web searches confirm that:

  1. CASCADE with ondelete="CASCADE" is a legitimate and recommended SQLModel/SQLAlchemy pattern, and it's a good idea to have cascade_delete configured alongside nullable=False on foreign keys
  2. When adding ondelete="CASCADE" to an existing foreign key, alembic will drop and recreate the constraint
  3. CASCADE delete is a standard pattern in real-world batch systems for cleanup operations

The review comment raised a valid concern about verifying CASCADE is intentional, but:

  • CASCADE with nullable=False is a standard, best-practice pattern
  • The code snippet shows both fields correctly configured
  • If this is a "cleanup PR aligning model with existing schema," CASCADE aligns with typical batch job handling
  • No evidence of audit/history concerns specific to batch_job model was found in context

The original review comment's request for verification is somewhat addressed through standard SQLModel/SQLAlchemy practices, but without access to the actual database state or migration files, I cannot definitively confirm whether this represents:

  1. Alignment with existing database constraints, or
  2. A breaking change introducing new cascade behavior

Given the constraints and the inability to examine the actual codebase files directly in this environment, I should provide guidance on verification.

Verify CASCADE delete behavior aligns with application requirements and confirm it matches existing database schema through migration review or database inspection.

The ondelete="CASCADE" pattern is appropriate for automatically deleting related records when a parent is deleted, and setting nullable=False alongside CASCADE is a standard configuration. However, confirm:

  1. Existing database constraints already implement CASCADE (if aligning existing schema) or expect application-level cascade handling
  2. Batch job deletion aligns with your data retention and audit policies
  3. If this PR introduces new CASCADE behavior (not in current schema), migration files properly drop and recreate affected foreign keys with the new constraint

If batch jobs serve audit/history purposes, consider whether CASCADE deletion is appropriate or if RESTRICT should be used instead to prevent accidental data loss.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
backend/app/models/evaluation.py (3)

94-97: JSONB metadata column aligns with Postgres usage; consider DB‑level default

Switching dataset_metadata to JSONB with nullable=False and a Python default_factory=dict correctly models a required JSONB column on the ORM side. If you expect inserts outside SQLModel/ORM (raw SQL, data loads), you may also want a database‑level default of {} in the Alembic migration to fully match this non‑nullable contract; otherwise this is fine as-is.


148-151: Consistent JSONB usage for config and score

Migrating both config (non‑nullable with default_factory=dict) and score (nullable) to JSONB keeps the model consistent with the evaluation dataset metadata and the Postgres schema, and avoids future JSON↔JSONB drift in Alembic. As with dataset_metadata, consider a DB‑level default for config if you rely on non‑ORM inserts, but the current model definition is otherwise solid.

Also applies to: 193-196


163-177: SET NULL semantics and dedicated embedding batch job FK look correct

Changing batch_job_id to ondelete="SET NULL" and introducing embedding_batch_job_id with the same SET NULL behavior matches the idea that evaluation runs should survive even if their backing batch jobs are cleaned up. The corresponding relationship definitions using explicit foreign_keys keep SQLAlchemy’s relationship resolution unambiguous. If you commonly query by batch_job_id or embedding_batch_job_id, you might later consider adding indexes on these columns via index=True or explicit Index entries, but that’s a tuning/usage decision rather than a blocker.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d854bbe and 68fe7b8.

📒 Files selected for processing (2)
  • backend/app/alembic/versions/6fe772038a5a_create_evaluation_run_table.py (4 hunks)
  • backend/app/models/evaluation.py (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/app/alembic/versions/6fe772038a5a_create_evaluation_run_table.py
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Use type hints in Python code (Python 3.11+ project)

Files:

  • backend/app/models/evaluation.py
backend/app/models/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Define SQLModel entities (database tables and domain objects) in backend/app/models/

Files:

  • backend/app/models/evaluation.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: checks (3.11.7, 6)
🔇 Additional comments (2)
backend/app/models/evaluation.py (2)

5-6: JSONB and Index imports are appropriate for the model changes

Bringing in Index and PostgreSQL JSONB matches their later usage in __table_args__ and the JSONB-backed columns, and keeps the imports lean and explicit. No changes needed here.


136-139: Composite indexes on (status, organization_id/project_id) look well‑targeted

Defining idx_eval_run_status_org and idx_eval_run_status_project directly in __table_args__ is a good fit if you frequently filter evaluations by status within an organization or project. This should help avoid future migration noise while improving query performance on common listing endpoints.

@AkhileshNegi AkhileshNegi merged commit 822426e into main Nov 19, 2025
3 checks passed
@AkhileshNegi AkhileshNegi deleted the enhancement/evaluation-migrations branch November 19, 2025 06:31
@coderabbitai coderabbitai bot mentioned this pull request Nov 28, 2025
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants